/**
 * 
 */
package logica;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;

import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import javax.swing.JOptionPane;



import ui.Kta;

/**
 * para el futuro deberia haber dos clases MyFile y luego dos clases que extiendan de ella
 * una con la todo lo importante de los directorios o discos agregados desde el catalogador y 
 * otra con todo lo que tenga que se refiera a levantar los archivos o base de datos
 * @author Dieguez
 *	
 */
public class MyFile {
	
	private File f;
	private Vector<MyFile> toplevel; // solo para la base de datos
	private String nombre;	// solo para la base de datos
	private int nro;
	private java.util.Date fechaLectura;
	private boolean isTopLevel=false;
	private Kta ref;
	private boolean isFromFile=false;
	private String type;
	private int size;
	private String date;
	private MyFile padre;
	private Vector<MyFile> subfiles;
	
	
	/**
	 * usado cuando se agrega un cd/dvd o se utiliza un directorio del disco
	 * @param archivo
	 * @param ref
	 */
	public MyFile(File archivo, Kta ref) {
		f=archivo;
		this.ref=ref;
		this.toplevel=null;
		this.fechaLectura = new java.util.Date();
		padre=null;
		subfiles=null;
		
	}

	/**
	 * contructor para las bases de datos,para la raiz y el primer nivel	
	 */
	public MyFile(String nom,Kta r) {
		nombre=nom;
		toplevel=new Vector<MyFile>();
		fechaLectura = new java.util.Date();
		ref=r;
		isFromFile=true;
		subfiles=null;
	}	
	
	
	/***
	 * usado cuando se crea un nodo a partir del archivo
	 * @param nom
	 * @param type
	 * @param size0
	 * @param date
	 * @param ref
	 */
	public MyFile(String tipo, String nom, String size, String date, Kta r,MyFile padre){
		this.type=tipo;
		this.isFromFile=true;
		this.nombre=nom;
		if(type.equals("CD_DVD")){
			this.isTopLevel=true;
			this.padre=padre;
			
		}
		
		this.size=Integer.valueOf(size).intValue();
		this.date=date;
		this.ref=r;
		
	}
	
	
	
	private boolean isDataBase(){
		if(this.toplevel!=null)
			return true;
		return false;
	}

	public String getName() {	 
		if(isDataBase()){
			return this.nombre;
		}
		else
		
		return f.getName();
	}
	
	public String getFecha(){
		return fechaLectura.toString();
	}

	public boolean isFile() {	
		if(isDataBase()){
			return false;
		}
		return f.isFile();
	}
	
	public File getFile(){
		return this.f;
	}

	public boolean isDirectory() {
		if(isDataBase()){
			return true;
		}			
		return f.isDirectory();
	}

	public Object[] listFiles() throws Errores {			
		if(isDataBase()){
			return toplevel.toArray();
		}
		MyFile t;
		Vector<MyFile> tmp = new Vector<MyFile>();
		
		try{
			for(File file : f.listFiles()){
				t = new MyFile(file,this.ref);
				t.setNro(nro);// le asigna el mismo nro de disco a todos sus hijos
				tmp.add(t);
			}
			return tmp.toArray();
		} catch(NullPointerException e){		
			throw new Errores(this.ref,0);			
		}
		
	}

	public long length() {
		if(isDataBase()){
			return this.toplevel.size();
		}
		
		return f.length();
	}
	
	// usado un disco desde la interfaz del programa
	public void addSubFile(MyFile f,boolean istoplevel) {
		f.isTopLevel=istoplevel;
		if(toplevel!=null){
			this.toplevel.add(f);
		}else{
			toplevel=new Vector();
			toplevel.add(f);
		}
	}
	
	//usado cuando se agrega un disco desde el archivo
	/*
	private void addSubFile(String nameFromFile, String tipo, String sizeFromFile,
			String dateFromFile) {
		this.toplevel.add(new MyFile(tipo,nameFromFile,sizeFromFile,dateFromFile,));
		
		
	}*/
	
	public void setNro(int i) {
		this.nro=i;
		
	}
	public int getNro() {		
		
		return nro;
		
	}
	
	public long getSize() throws Errores{
		
		if(this.isDirectory()){ // si es un directorio
			Object[] tmp=this.listFiles();
			if(tmp!=null)
				return tmp.length;
			return 0;			
		}
		
		// si es un archivo
		long tamanio=0;
		long tmp=(this.length()/1000);
		if(tmp==0)
			tamanio=1;
		else
			tamanio=tmp;
		return tamanio;
		
	}
	public String getAbsolutePath(){
		return f.getAbsolutePath();
	}
	public void save(BufferedWriter archivoAguardar, String tabs
			, Kta thiss) throws IOException, Errores {
		
		if(isDataBase()){ // es la base de datos principal
			
			archivoAguardar.newLine();
			archivoAguardar.newLine();
			archivoAguardar.write("<K-taloga_Database Name=\""+this.getName()+"\">");
				
			for(MyFile hijo : this.toplevel){
				hijo.save(archivoAguardar, tabs, thiss);				
			}
			
			archivoAguardar.newLine();
			archivoAguardar.write("</Broken_X_Database>");
				
			
		} else if(this.isTopLevel){ // es un cd o dvd inserto en la base de datos
			
			archivoAguardar.newLine();
			archivoAguardar.write(tabs+"<CD_DVD Name=\""+this.getName()+"\" Size=\""+this.getSize()+"\" Date=\""+this.getFecha()+"\">");			
			for(Object hijo : this.listFiles()){
				((MyFile)hijo).save(archivoAguardar, tabs+"\t", thiss);
			}
			archivoAguardar.newLine();
			archivoAguardar.write(tabs+"</CD_DVD>" +
					"");	
			
			
		} else{ // es un archivo o carpeta comun del cd o dvd
			
			if(this.isDirectory()){
				//<File_Folder Name="1 peso, 1 dolar" Size="734043840" Date="20/01/2008 18:43">
				
				archivoAguardar.newLine();
				archivoAguardar.write(tabs+"<File_Folder Name=\""+this.getName()+"\" Size=\""+this.getSize()+"\" Date=\""+this.getFecha()+"\">");
				//archivoAguardar.newLine();
					
				for(Object hijo : this.listFiles()){
					((MyFile)hijo).save(archivoAguardar, tabs+"\t", thiss);
				}
				archivoAguardar.newLine();
				archivoAguardar.write(tabs+"</File_Folder>");
				//archivoAguardar.newLine();
				
			} else if(this.isFile()){
				//<File Name="afiche.jpg" Size="266389" Date="20/01/2008 17:32"/>
				archivoAguardar.newLine();
				archivoAguardar.write(tabs+"<File Name=\""+this.getName()+"\" Size=\""+this.getSize()+"\" Date=\""+this.getFecha()+"\">");
				//archivoAguardar.newLine();					
				
			}
		}		
		
	}
	
	/**
	 * hay que implementar toda la logica para levantar el archivo
	 * hasta ahora solo se muestra por consola
	 * @param archivoLeer
	 * @param tabs
	 * @param file
	 * @throws IOException
	 */
	public void openDB_old(BufferedReader archivoLeer, String tabs, MyFile file) throws IOException {
				
		String nuevaLinea = archivoLeer.readLine();
		//System.out.println(nuevaLinea);
		String [] linea=null;
		linea=nuevaLinea.split("=");
		
		
		//if(nuevaLinea.startsWith("<K-taloga_Database Name")){ // otra forma
		if(linea[0].equals("<K-taloga_Database Name")){ // es la base de datos principal
					
			nombre=getEntreComillas(linea[1]);
			//this.nombre=linea[1].substring(1,linea[1].length()-2);
			//System.out.println("**************************************************");
			System.out.println("linea: "+nuevaLinea);
			System.out.println("nombre de la base de datos: "+nombre+"\n");
			this.openDB_old(archivoLeer, tabs,this);
			
		} else if(linea[0].equals(tabs+"<CD_DVD Name")){ // es un cd o dvd 
			
			nombre=getEntreComillas(linea[1]);
			System.out.println("linea: "+nuevaLinea);			
			System.out.println("nombre del cd/dvd: "+nombre+"\n");
			tabs+="\t";
			this.openDB_old(archivoLeer, tabs,this);
			
		} else if(linea[0].equals(tabs+"<File_Folder Name")){ // es un archivo o carpeta comun del cd o dvd
			
			nombre=getEntreComillas(linea[1]);
			System.out.println("linea: "+nuevaLinea);			
			System.out.println("nombre del File_Folder: "+nombre+"\n");
			tabs+="\t";
			this.openDB_old(archivoLeer, tabs,this);
			
		} else if(linea[0].equals(tabs+"<File Name")){
			
			nombre=getEntreComillas(linea[1]);
			System.out.println("linea: "+nuevaLinea);			
			System.out.println("nombre del File_Folder: "+nombre+"\n");
			//tabs+="\t"; es un archivo
			this.openDB_old(archivoLeer, tabs,this);
			
		}
		
		/* tags de cierre */		
		
		else if(linea[0].endsWith("</File_Folder>")){ // es un tag de cierre de carpeta
			
			System.out.println(linea[0]);
			//archivoLeer.readLine();
			tabs=tabs.substring(0, tabs.length()-1);
			this.openDB_old(archivoLeer, tabs,this);	
			
		} else if(linea[0].endsWith("</CD_DVD>")){ // es un tag de cierre de carpeta
			
			System.out.println(linea[0]);
			//archivoLeer.readLine();
			tabs=tabs.substring(0, tabs.length()-1);
			this.openDB_old(archivoLeer, tabs,this);
			
		} else if(linea[0].endsWith("</Broken_X_Database>")){ // fin archivo
						
			System.out.println(linea[0]);
			//archivoLeer.readLine();
			tabs=tabs.substring(0, tabs.length()-1);
			archivoLeer.close();			
		}		
		
	}
	
	public MyFile openDB(BufferedReader archivoLeer, String tabs, Kta kta) throws IOException {
		MyFile nodonuevo=null;
		MyFile salida=null;
		String nuevaLinea=null;
		String [] linea=null;
		String nameFromFile=null,sizeFromFile=null,dateFromFile=null,nameDBFromFile=null;
		MyFile nodoactual=null;
		
		
		
		while((nuevaLinea=archivoLeer.readLine())!=null){	
			
			linea=nuevaLinea.split("=");						
			
			//if(nuevaLinea.startsWith("<K-taloga_Database Name")){ // otra forma			
			
			if(linea[0].equals("<K-taloga_Database Name")){ // es la base de datos principal
				
				// no tiene datos importantes mas que el nombre		
				
				nameFromFile=getEntreComillas(linea[1]);	
				
				System.out.println("linea: "+nuevaLinea);
				System.out.println(" nombre de la base de datos: "+nameFromFile+"\n");
				salida = new MyFile(nameFromFile, kta);		
				nameDBFromFile=nameFromFile;
				nodoactual = salida;
				
				
			} else if(linea[0].equals(tabs+"<CD_DVD Name")){ 
				// es un cd o dvd 
				
				if(linea.length>=4){
					nameFromFile=getEntreComillas(linea[1]);
					sizeFromFile=getEntreComillas(linea[2]);
					dateFromFile=getEntreComillas(linea[3]);					
				}	
				
				nodoactual = new MyFile("CD_DVD",nameFromFile,sizeFromFile,dateFromFile,kta,null);
				salida.toplevel.add(nodoactual);
				
				//salida.addSubFile(nameFromFile,"CD_DVD",sizeFromFile,dateFromFile);
				
				System.out.println("linea: "+nuevaLinea);			
				System.out.println("nombre del cd/dvd: "+nameFromFile+"\n");
				tabs+="\t";
				
				
			} else if(linea[0].equals(tabs+"<File_Folder Name")){ 
				// es un archivo o carpeta comun del cd o dvd
				
				if(linea.length>=4){
					nameFromFile=getEntreComillas(linea[1]);
					sizeFromFile=getEntreComillas(linea[2]);
					dateFromFile=getEntreComillas(linea[3]);					
				}else{
					System.out.println("if(linea.length>=4) ==> no entro " +
							"\n"+ "linea 391 de MyFile");
				}
				
				
				nodonuevo = new MyFile("File_Folder",nameFromFile,sizeFromFile,dateFromFile,kta, nodoactual);
				nodoactual.addSubFile(nodonuevo,false);
				nodoactual=nodonuevo;
				nodonuevo=null;
				
				System.out.println("linea: "+nuevaLinea);			
				System.out.println("nombre del File_Folder: "+nameFromFile+"\n");
				tabs+="\t";			
				
				
			} else if(linea[0].equals(tabs+"<File Name")){
				
				if(linea.length>=4){
					nameFromFile=getEntreComillas(linea[1]);
					sizeFromFile=getEntreComillas(linea[2]);
					dateFromFile=getEntreComillas(linea[3]);					
				}else{
					System.out.println("if(linea.length>=4) ==> no entro "
							+ "\nlinea 412 de MyFile");
				}
				
				nodonuevo = new MyFile("File Name",nameFromFile,sizeFromFile,dateFromFile,kta, nodoactual);
				nodoactual.addSubFile(nodonuevo,false);
				
				
				nameFromFile=getEntreComillas(linea[1]);
				System.out.println("linea: "+nuevaLinea);			
				System.out.println("nombre del File_Folder: "+nameFromFile+"\n");
				//tabs+="\t"; es un archivo
				//this.openDB(archivoLeer, tabs,this);
				
			}
			
			/* tags de cierre */		
			
			else if(linea[0].endsWith("</File_Folder>")){ // es un tag de cierre de carpeta
				
				System.out.println(linea[0]);
				//archivoLeer.readLine();
				tabs=tabs.substring(0, tabs.length()-1);
				//this.openDB(archivoLeer, tabs,this);	
				
			} else if(linea[0].endsWith("</CD_DVD>")){ // es un tag de cierre de carpeta
				
				System.out.println(linea[0]);
				//archivoLeer.readLine();
				tabs=tabs.substring(0, tabs.length()-1);
				//this.openDB(archivoLeer, tabs,this);
				
			} else if(linea[0].endsWith("</Broken_X_Database>")){ // fin archivo
							
				System.out.println(linea[0]);
				//archivoLeer.readLine();
				tabs=tabs.substring(0, tabs.length()-1);				
			}		
			
			
		} // fin while
		
		JOptionPane.showMessageDialog(null, "el nombre de la base es: "+nameDBFromFile);
		
		MyFile retorno = new MyFile(nameDBFromFile, kta);
		
		return retorno;
		
	}
	
	
	
	public void openDBNew(BufferedReader archivoLeer, String tabs, MyFile file) throws IOException {
		
	}
	
	/**
	 * saca el texto que extiste entre las dos primeras comillas dobles
	 * del string de entrada
	 * @param input
	 * @return 
	 */
	private String getEntreComillas(String input){
		String salida=null;
		int indI=-1,indF=-1;
		if(!input.isEmpty()){
			indI=input.indexOf('"');
			indF=input.indexOf('"', ++indI);
			if(indI!=-1 && indF!=-1 && indI>=0 && indF>=indI){
				salida=input.substring(indI,indF);
			} 
			else {
				salida=input;
				
			}
		}		
		return salida;
	}
	
	
}
